package com.athuahua.security.component;

import jakarta.annotation.Resource;
import org.springframework.r2dbc.core.DatabaseClient;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

/**
 * @Author: huahua
 * @Date: 2024/12/13 0013
 * @Time: 12:59
 * @Description: AppReactiveUserDetailsService
 */
@Component //定义去数据库按照用户名查询用户
public class ARUDS implements ReactiveUserDetailsService {


    @Resource
    private DatabaseClient databaseClient;


    PasswordEncoder passwordEncoder;

    public ARUDS(DatabaseClient databaseClient) {
        this.passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

    //自定义如何按照用户名查询信息
    @Override
    public Mono<UserDetails> findByUsername(String username) {

        Mono<UserDetails> map1 = databaseClient.sql(
                        "select u.* ,r.id rid,r.name,r.value , pm.id pid , pm.value pvalue , pm.description\n" +
                                "from t_user u\n" +
                                "left join t_user_role ur on ur.user_id = u.id\n" +
                                "left join t_roles r on r.id = ur.role_id\n" +
                                "left join t_role_perm rp on rp.role_id = r.id\n" +
                                "left join t_perm pm on rp.perm_id = pm.id\n" +
                                "where u.username = ? limit 1")
                .bind(0, username)
                .fetch()
                .one() //使用时要改成all
                .map(map -> {
                    UserDetails build = User.builder()
                            .username(username)
                            .password(map.get("password").toString())
                            .passwordEncoder(str -> passwordEncoder.encode(str))
                            .authorities("delete","view")
                            //.authorities(new SimpleGrantedAuthority("delete")) //简写权限
                            .roles("admin", "sale")
                            .build();
                    return build;
                });


        return map1;
    }
}
